import React, {
    Children,
    forwardRef,
    ReactNode,
    useEffect,
    useImperativeHandle,
    useMemo,
    useState
} from 'react';
import {
    CommonEventFunction,
    Swiper as TaroSwiper,
    SwiperItem as TaroSwiperItem,
    SwiperProps as TaroSwiperProps,
    View
} from '@tarojs/components';
import { TComponent } from '@material/typeing';
import { clsx } from 'react-runtime-clsx';
import { pxCheck } from '@/utils';
import $style from './index.scss';
export interface SwiperProps
    extends Omit<TaroSwiperProps, 'ref' | 'className' | 'style'>,
        TComponent {
    width: number;
    height: number | string;
    direction: 'horizontal' | 'vertical';
    indicator: ReactNode;
    autoPlay: boolean;
    loop: boolean;
    defaultValue: number;
    onChange: CommonEventFunction<TaroSwiperProps.onChangeEventDetail>;
}

const defaultProps = {
    direction: 'horizontal',
    indicator: false,
    autoPlay: false,
    loop: false,
    defaultValue: 0,
    style: {}
} as SwiperProps;

const Swiper = forwardRef((props: Partial<SwiperProps>, ref) => {
    const {
        width,
        height,
        className,
        children,
        indicator,
        loop,
        autoPlay,
        direction,
        defaultValue,
        onChange,
        style,
        ...rest
    } = {
        ...defaultProps,
        ...props
    };
    const [current, setCurrent] = useState(defaultValue);
    const childrenCount = useMemo(() => {
        let c = 0;
        React.Children.map(children, (child, index) => {
            c += 1;
        });
        return c;
    }, [children]);
    useEffect(() => {
        setCurrent(defaultValue);
    }, [defaultValue]);
    const renderIndicator = () => {
        if (React.isValidElement(indicator)) return indicator;
        if (indicator) {
            return (
                <div
                    className={[
                        $style.indicator,
                        { [$style['indicator-vertical']]: direction === 'vertical' }
                    ]}
                >
                    <div>hello</div>
                </div>
            );
        }
        return null;
    };
    const handleOnChange: CommonEventFunction<TaroSwiperProps.onChangeEventDetail> = (value) => {
        setCurrent(value.detail.current);
    };
    useImperativeHandle(ref, () => ({
        to: (value: number) => {
            setCurrent(value);
        },
        next: () => {
            if (loop) {
                setCurrent((current + 1) % childrenCount);
            } else {
                setCurrent(current + 1 >= childrenCount ? current : current + 1);
            }
        },
        prev: () => {
            if (loop) {
                let next = current - 1;
                next = next < 0 ? childrenCount + next : next;
                setCurrent(next % childrenCount);
            } else {
                setCurrent(current - 1 <= 0 ? 0 : current - 1);
            }
        }
    }));
    return (
        <View
            className={clsx([$style.swiper, className])}
            style={{
                ...style,
                width: !width ? '100%' : pxCheck(width),
                height: !height ? '150px' : pxCheck(height)
            }}
        >
            <View
                className={$style.inner}
                style={{
                    width: !width ? '100%' : pxCheck(width),
                    height: !height ? '150px' : pxCheck(height)
                }}
            >
                <TaroSwiper
                    current={current}
                    circular={loop}
                    autoplay={autoPlay}
                    vertical={direction === 'vertical'}
                    indicatorDots={false}
                    onChange={(e) => {
                        handleOnChange(e);
                        props.onChange?.(e);
                    }}
                    style={{
                        width: !width ? '100%' : pxCheck(width),
                        height: !height ? '150px' : pxCheck(height)
                    }}
                    {...rest}
                >
                    {Children.toArray(children).map((child, index) => {
                        let className;
                        if (React.isValidElement(child)) {
                            className = child.props.className;
                        }
                        return (
                            <TaroSwiperItem
                                className={className}
                                key={index}
                            >
                                {child}
                            </TaroSwiperItem>
                        );
                    })}
                </TaroSwiper>
            </View>
            {renderIndicator()}
        </View>
    );
});

Swiper.displayName = 'Swiper';

export default Swiper;
